setup

loading in files

ksheader<-read.table("65183_65184.CDS-CDS.last.tdd10.cs0.filtered.dag.all.go_D20_g10_A5.aligncoords.gcoords.ks.txt",comment.char ="",skip = 2,nrows = 1) %>% select(-V13) %>% rename() 
Tweak header names and add to main file.
ksheader$V1<-"Ks"
ksheader$V3<-"a_dbgenomeid_chr"
ksheader$V7<-"b_dbgenomeid_chr"
ksfile<-read.table("65183_65184.CDS-CDS.last.tdd10.cs0.filtered.dag.all.go_D20_g10_A5.aligncoords.gcoords.ks.txt", comment.char = "#",header =FALSE)
colnames(ksfile)<- as.character(ksheader)

File parsing

Change “|” separated entries into sep columns

colnames(ksfile)
 [1] "Ks"                                                                                    
 [2] "Kn"                                                                                    
 [3] "a_dbgenomeid_chr"                                                                      
 [4] "chr1||start1||stop1||name1||strand1||type1||db_feature_id1||genome_order1||percent_id1"
 [5] "start1"                                                                                
 [6] "stop1"                                                                                 
 [7] "b_dbgenomeid_chr"                                                                      
 [8] "chr2||start2||stop2||name2||strand2||type2||db_feature_id2||genome_order2||percent_id2"
 [9] "start2"                                                                                
[10] "stop2"                                                                                 
[11] "eval"                                                                                  
[12] "block_score"                                                                           
ksfile_split<-ksfile %>% 
      separate_wider_delim(
        cols=c("chr1||start1||stop1||name1||strand1||type1||db_feature_id1||genome_order1||percent_id1"),
          delim = "||", 
            names = c("chr1","start1_og","stop1_og","name1",
                        "strand1","type1","db_feature_id1","genome_order1","percent_id1")) %>%
      separate_wider_delim(
        cols=c("chr2||start2||stop2||name2||strand2||type2||db_feature_id2||genome_order2||percent_id2"),
          delim = "||", 
            names = c("chr2","start2_og","stop2_og","name2",
                        "strand2","type2","db_feature_id2","genome_order2","percent_id2")) 
## og start and stop are opposite of the other positions bc on minus strand

Tidy up and filter Ks data

Table of just Ks values and gene IDs and chrs, filter by max 0.5 Ks.

ks_df<- ksfile_split %>% 
  select(Ks,chr1,start1,start1_og,stop1,name1,chr2,start2,stop2,name2) %>%
  mutate(name1=stringr::str_replace(name1,"-RA","")) %>%
  mutate(name2=stringr::str_replace(name2,"-RA","")) %>%
  mutate(start1_mb = start1/1e6)
## annotate plot - these are PAR/sex-linked region boundaries
vlines <- c(71,261,367)
## medians of sex linked regions
ks_df_md <- ks_df %>% 
  filter(Ks< 0.5) %>%
  mutate(region = case_when((chr1 == "X" & start1_mb <=71) ~ "PAR1",
    ((chr1 == "X" & start1_mb >71 & start1_mb <=261)) ~ "OldSLR",
    ((chr1 == "X" & start1_mb >261 & start1_mb <=367)) ~ "NewSLR",
    ((chr1 == "X" & start1_mb > 367 ~ "PAR2")))) %>% 
  group_by(., region) %>% 
  mutate(mdn = median(Ks))
cowplot::plot_grid(a1,a2,x,a4)
Warning: Removed 10 rows containing missing values (`geom_point()`).Warning: Removed 5 rows containing missing values (`geom_point()`).Warning: Removed 18 rows containing missing values (`geom_point()`).Warning: Removed 5 rows containing missing values (`geom_point()`).

Exploratory plots

Raw Ks values and chromosome medians

Ks in windows of 100 genes

Integrate salicifolius homology data

sal_raw <- data.table::fread("~/Dropbox/rumex_pangenome_annotation/pg_sal_wide_synonly.txt")

salkey<-readr::read_delim("input_to_output.txt",col_names =c("old","new"),show_col_types = FALSE)
salkey<-salkey %>% mutate(fix=str_replace(old, "\\=", "\\_")) %>%
  mutate(.,fix=str_replace(fix, "\\;", "\\_")) %>% select(fix,new)
salkey<-as.data.frame(salkey)

sal_df <- sal_raw %>% filter(salicifolius !="",hap1!="",hap2!="") %>% 
  dplyr::select(interpChr,salicifolius,hap1,hap2,start) %>% mutate(start_salmb = start/1e6) %>% 
  dplyr::mutate(salchr = case_when(interpChr == salkey[1,1] ~ salkey[1,2], 
                        interpChr == salkey[2,1] ~ salkey[2,2], 
                        interpChr == salkey[3,1] ~ salkey[3,2],
                        interpChr == salkey[4,1] ~ salkey[4,2],
                        interpChr == salkey[5,1] ~ salkey[5,2],
                        interpChr == salkey[6,1] ~ salkey[6,2],
                        interpChr == salkey[7,1] ~ salkey[7,2],
                        interpChr == salkey[8,1] ~ salkey[8,2],
                        interpChr == salkey[9,1] ~ salkey[9,2],
                        interpChr == salkey[10,1] ~ salkey[10,2])) #%>% 
  #unite(., scafpos,c("salchr","start_salmb"))


ks_df_sal <- left_join(ks_df_md, sal_df, by = c("name1"="hap1","name2"="hap2"))
Warning: Detected an unexpected many-to-many relationship between `x` and `y`.
windowmaker_sal<- function(df,win,start){df %>%
  group_by(salchr) %>%
  arrange(salicifolius,salchr, start) %>%
  mutate(Ks_win = slider::slide_dbl(Ks, median, .before = win/2, .after = win/2,.step = 1,.complete =T))}
orderlist<-c("Scaffold_4","Scaffold_8","Scaffold_7",
             "Scaffold_5","Scaffold_3","Scaffold_6","Scaffold_10",
             "Scaffold_1","Scaffold_2","Scaffold_9")

ks_df_sal <- transform(ks_df_sal, salchr = factor(salchr, levels = orderlist))
#levels(ks_df_sal$salchr)
ks_win100_sal<-windowmaker_sal(ks_df_sal,win = 100, start_salmb)
ks_win10_sal<-windowmaker_sal(kd_df_sal, win = 10, start_salmb)
Error: object 'kd_df_sal' not found

raw Ks colored by salicifolius chromosome homology

raw Ks organized by salicifolius gene order

windowed Ks for X genes in salicifolius homologous gene order

windowed Ks for all chr in sal order

Ks windows X, line and dotplot

Final plots for publication

pubTheme <-
  theme_cowplot(font_size = 12,rel_small    =0.75) +
  theme(legend.title = element_blank())

basic four-panel windowed Ks

recreate dotplot for multipanel plot

Invert some chrs in plot

## read in file of cleaned COGE anchors created from anchorwaveplots.Rmd 
anchors_mb<-read_delim("data/anchors_mb.txt")
##
max_query_mb <- function(chr){max(filter(anchors_mb,newChr ==chr)$queryMb)}
#max_query_mb("Y")                          

anchors_inv<-anchors_mb %>% group_by(newChr) %>% 
  mutate(newstartMb = case_when(newChr == "Y" ~ (max_query_mb("Y") - queryMb),
                                newChr =="A1" ~ queryMb,
                                newChr =="A2" ~ (max_query_mb("A2") - queryMb),
                                newChr =="A4" ~ (max_query_mb("A4") - queryMb)))

making it multi-panel

comboplot<-cowplot::plot_grid(dotplot,ksplot,nrow=2,align="v",axis="lr")
Warning: Removed 3068 rows containing missing values (`geom_point()`).Warning: Removed 400 rows containing missing values (`geom_line()`).
comboplot<-cowplot::plot_grid(dotplot,ksplot,nrow=2,align="v",axis="lr")
Warning: Removed 3068 rows containing missing values (`geom_point()`).Warning: Removed 400 rows containing missing values (`geom_line()`).
comboplot 

Need to separate out Y1 and Y2? #### color by hap2 chromosome

To do: * next:gene loss plots, ASE * save as jpg and PNG for pub * figure legends in text below (goog doc) * list of silenced genes from ASE analysis - combine w TE

chi square

ct

    Pearson's Chi-squared test

data:  fishmat
X-squared = 3.0634, df = 1, p-value = 0.08007
LS0tCnRpdGxlOiAiS3MgcGxvdHMgZm9yIGdlbm9tZSBwYXBlciIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQojIyMgc2V0dXAKYGBge3IgaW5jbHVkZT1GQUxTRX0KCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNvd3Bsb3QpCgpgYGAKIyMjIyBsb2FkaW5nIGluIGZpbGVzCmBgYHtyfQprc2hlYWRlcjwtcmVhZC50YWJsZSgiNjUxODNfNjUxODQuQ0RTLUNEUy5sYXN0LnRkZDEwLmNzMC5maWx0ZXJlZC5kYWcuYWxsLmdvX0QyMF9nMTBfQTUuYWxpZ25jb29yZHMuZ2Nvb3Jkcy5rcy50eHQiLGNvbW1lbnQuY2hhciA9IiIsc2tpcCA9IDIsbnJvd3MgPSAxKSAlPiUgc2VsZWN0KC1WMTMpICU+JSByZW5hbWUoKSAKCmBgYAojIyMjIyBUd2VhayBoZWFkZXIgbmFtZXMgYW5kIGFkZCB0byBtYWluIGZpbGUuCmBgYHtyfQprc2hlYWRlciRWMTwtIktzIgprc2hlYWRlciRWMzwtImFfZGJnZW5vbWVpZF9jaHIiCmtzaGVhZGVyJFY3PC0iYl9kYmdlbm9tZWlkX2NociIKa3NmaWxlPC1yZWFkLnRhYmxlKCI2NTE4M182NTE4NC5DRFMtQ0RTLmxhc3QudGRkMTAuY3MwLmZpbHRlcmVkLmRhZy5hbGwuZ29fRDIwX2cxMF9BNS5hbGlnbmNvb3Jkcy5nY29vcmRzLmtzLnR4dCIsIGNvbW1lbnQuY2hhciA9ICIjIixoZWFkZXIgPUZBTFNFKQpjb2xuYW1lcyhrc2ZpbGUpPC0gYXMuY2hhcmFjdGVyKGtzaGVhZGVyKQpgYGAKIyMjIyBGaWxlIHBhcnNpbmcKQ2hhbmdlICJ8IiBzZXBhcmF0ZWQgZW50cmllcyBpbnRvIHNlcCBjb2x1bW5zCmBgYHtyfQpjb2xuYW1lcyhrc2ZpbGUpCmtzZmlsZV9zcGxpdDwta3NmaWxlICU+JSAKICAgICAgc2VwYXJhdGVfd2lkZXJfZGVsaW0oCiAgICAgICAgY29scz1jKCJjaHIxfHxzdGFydDF8fHN0b3AxfHxuYW1lMXx8c3RyYW5kMXx8dHlwZTF8fGRiX2ZlYXR1cmVfaWQxfHxnZW5vbWVfb3JkZXIxfHxwZXJjZW50X2lkMSIpLAogICAgICAgICAgZGVsaW0gPSAifHwiLCAKICAgICAgICAgICAgbmFtZXMgPSBjKCJjaHIxIiwic3RhcnQxX29nIiwic3RvcDFfb2ciLCJuYW1lMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJzdHJhbmQxIiwidHlwZTEiLCJkYl9mZWF0dXJlX2lkMSIsImdlbm9tZV9vcmRlcjEiLCJwZXJjZW50X2lkMSIpKSAlPiUKICAgICAgc2VwYXJhdGVfd2lkZXJfZGVsaW0oCiAgICAgICAgY29scz1jKCJjaHIyfHxzdGFydDJ8fHN0b3AyfHxuYW1lMnx8c3RyYW5kMnx8dHlwZTJ8fGRiX2ZlYXR1cmVfaWQyfHxnZW5vbWVfb3JkZXIyfHxwZXJjZW50X2lkMiIpLAogICAgICAgICAgZGVsaW0gPSAifHwiLCAKICAgICAgICAgICAgbmFtZXMgPSBjKCJjaHIyIiwic3RhcnQyX29nIiwic3RvcDJfb2ciLCJuYW1lMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJzdHJhbmQyIiwidHlwZTIiLCJkYl9mZWF0dXJlX2lkMiIsImdlbm9tZV9vcmRlcjIiLCJwZXJjZW50X2lkMiIpKSAKIyMgb2cgc3RhcnQgYW5kIHN0b3AgYXJlIG9wcG9zaXRlIG9mIHRoZSBvdGhlciBwb3NpdGlvbnMgYmMgb24gbWludXMgc3RyYW5kCmBgYAojIyMjIFRpZHkgdXAgYW5kIGZpbHRlciBLcyBkYXRhClRhYmxlIG9mIGp1c3QgS3MgdmFsdWVzIGFuZCBnZW5lIElEcyBhbmQgY2hycywgZmlsdGVyIGJ5IG1heCAwLjUgS3MuCmBgYHtyfQprc19kZjwtIGtzZmlsZV9zcGxpdCAlPiUgCiAgc2VsZWN0KEtzLGNocjEsc3RhcnQxLHN0YXJ0MV9vZyxzdG9wMSxuYW1lMSxjaHIyLHN0YXJ0MixzdG9wMixuYW1lMikgJT4lCiAgbXV0YXRlKG5hbWUxPXN0cmluZ3I6OnN0cl9yZXBsYWNlKG5hbWUxLCItUkEiLCIiKSkgJT4lCiAgbXV0YXRlKG5hbWUyPXN0cmluZ3I6OnN0cl9yZXBsYWNlKG5hbWUyLCItUkEiLCIiKSkgJT4lCiAgbXV0YXRlKHN0YXJ0MV9tYiA9IHN0YXJ0MS8xZTYpCiMjIGFubm90YXRlIHBsb3QgLSB0aGVzZSBhcmUgUEFSL3NleC1saW5rZWQgcmVnaW9uIGJvdW5kYXJpZXMKdmxpbmVzIDwtIGMoNzEsMjYxLDM2NykKIyMgbWVkaWFucyBvZiBzZXggbGlua2VkIHJlZ2lvbnMKa3NfZGZfbWQgPC0ga3NfZGYgJT4lIAogIGZpbHRlcihLczwgMC41KSAlPiUKICBtdXRhdGUocmVnaW9uID0gY2FzZV93aGVuKChjaHIxID09ICJYIiAmIHN0YXJ0MV9tYiA8PTcxKSB+ICJQQVIxIiwKICAgICgoY2hyMSA9PSAiWCIgJiBzdGFydDFfbWIgPjcxICYgc3RhcnQxX21iIDw9MjYxKSkgfiAiT2xkU0xSIiwKICAgICgoY2hyMSA9PSAiWCIgJiBzdGFydDFfbWIgPjI2MSAmIHN0YXJ0MV9tYiA8PTM2NykpIH4gIk5ld1NMUiIsCiAgICAoKGNocjEgPT0gIlgiICYgc3RhcnQxX21iID4gMzY3IH4gIlBBUjIiKSkpKSAlPiUgCiAgZ3JvdXBfYnkoLiwgcmVnaW9uKSAlPiUgCiAgbXV0YXRlKG1kbiA9IG1lZGlhbihLcykpCgpgYGAKCmBgYHtyfQphMTwta3NfcGxvdF9hdXRvKGtzX2RmLCJBMSIsTkEpCmEyPC1rc19wbG90X2F1dG8oa3NfZGYsIkEyIixOQSkKYTQ8LWtzX3Bsb3RfYXV0byhrc19kZiwiQTQiLE5BKQp4PC1rc19wbG90X2F1dG8oa3NfZGYsICJYIixOQSkKY293cGxvdDo6cGxvdF9ncmlkKGExLGEyLHgsYTQpCmdnc2F2ZSgia3NfYWxsX25vbGltaXQuanBnIix3aWR0aD04LGhlaWdodD02KQpgYGAKCiMjIyBFeHBsb3JhdG9yeSBwbG90cwojIyMjIFJhdyBLcyB2YWx1ZXMgYW5kIGNocm9tb3NvbWUgbWVkaWFucwpgYGB7cn0Ka3NfcGxvdF9hdXRvPC1mdW5jdGlvbihkZixjaHIseV9saW0pe2dncGxvdChmaWx0ZXIoZGYsY2hyMSA9PSBjaHIpLCBhZXMoc3RhcnQxX21iKSkgKwogIGdlb21fcG9pbnQoYWVzKHk9S3MsYWxwaGEgPSAwLjUpKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgeWxpbSgwLHlfbGltKSArCiAgeGxhYihwYXN0ZSgicG9zaXRpb24gb24gY2hyb21vc29tZSIsIGNociwgIihNYikiKSl9IAojIFggY2hyIGN1c3RvbWl6YXRpb24Ka3NfcGxvdF9YPC0gZnVuY3Rpb24oZGYsY2hyLHlfbGltKXtrc19wbG90X2F1dG8oZGYsY2hyLHlfbGltKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PXZsaW5lcywgbGluZXR5cGUgPSAiZGFzaGVkIikgKyAKICBhbm5vdGF0ZSgidGV4dCIsIHggPSAuMzUqKDcxKSwgeSA9IHlfbGltIC0gMC4wNSwgbGFiZWwgPSAiUEFSMSIsc2l6ZT00KSArCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gLjUqKDcxKzI2MSksIHkgPSB5X2xpbSAtIDAuMDUsIGxhYmVsID0gIk9sZCBzZXgtbGlua2VkXG4gcmVnaW9uIixzaXplID00KSArCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gLjUqKDI2MSszNjcpLCB5ID0geV9saW0gLSAwLjA1LCBsYWJlbCA9ICJOZXdcbiBzZXgtbGlua2VkXG4gcmVnaW9uIixzaXplPTQpICsKICBhbm5vdGF0ZSgidGV4dCIsIHggPSAuNSooMzY3KzUwMCksIHkgPSB5X2xpbSAtIDAuMDUsIGxhYmVsID0gIlBBUjIiLHNpemU9NCkgKyAKICBnZW9tX3N0ZXAoYWVzKHkgPSBtZG4sIGNvbG91ciA9ICJyZWQiKSl9CgoKI2dnc2F2ZSgia3NfZ2VuZXMuanBnIix3aWR0aD02LGhlaWdodD00LHVuaXRzID0gImluIikKYTE8LWtzX3Bsb3RfYXV0byhrc19kZl9tZCwiQTEiLE5BKQphMjwta3NfcGxvdF9hdXRvKGtzX2RmX21kLCJBMiIsTkEpCmE0PC1rc19wbG90X2F1dG8oa3NfZGZfbWQsIkE0IixOQSkKY293cGxvdDo6cGxvdF9ncmlkKGExLGEyLHhwbG90LGE0KQpnZ3NhdmUoImtzX2FsbF9ub2xpbWl0LmpwZyIsd2lkdGg9NixoZWlnaHQ9NCkKI2dnc2F2ZSgia3NfZ2VuZXNfeC5qcGciLHdpZHRoID0gNiwgaGVpZ2h0ID0gNCwgdW5pdHMgPSAiaW4iKQoja3NfZGZfbWRfMDI8LWtzX2RmX21kICU+JSBmaWx0ZXIoS3M8MC4yKQprc19wbG90X1goKGtzX2RmX21kICU+JSBmaWx0ZXIoS3M8MC4yKSksIlgiLDAuMykgKyB5bGFiKCJLcyBmaWx0ZXIgMC4yIikKa3NfcGxvdF9hdXRvKGtzX2RmX21kICU+JSBmaWx0ZXIoS3M8MC4yKSwiQTIiLE5BKSArIHlsYWIoIktzIGZpbHRlciAwLjIiKQojZ2dzYXZlKCJrc19nZW5lc194XzAyLmpwZyIsd2lkdGggPSA2LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIpCmBgYAojIyMjIEtzIGluIHdpbmRvd3Mgb2YgMTAwIGdlbmVzCmBgYHtyfQpsaWJyYXJ5KHNsaWRlcikKIHdpbmRvd21ha2VyPC0gZnVuY3Rpb24oZGYsd2luLGtzKXtrc19kZl9tZCAlPiUgZmlsdGVyKEtzPGtzKSAlPiUKICBncm91cF9ieShjaHIxKSAlPiUKICBhcnJhbmdlKG5hbWUxLGNocjEsIHN0YXJ0MV9tYikgJT4lCiAgbXV0YXRlKEtzX3dpbiA9IHNsaWRlcjo6c2xpZGVfZGJsKEtzLCBtZWRpYW4sIC5iZWZvcmUgPSB3aW4vMiwgLmFmdGVyID0gd2luLzIsLnN0ZXAgPSAxLC5jb21wbGV0ZSA9VCkpfQprc193aW4xMDA8LXdpbmRvd21ha2VyKGtzX2RmX21kLHdpbiA9IDEwMCwwLjIpCmtzX3dpbjEwMF9rczM8LXdpbmRvd21ha2VyKGtzX2RmX21kLHdpbj0xMDAsMC4zKQoKa3NfcGxvdF93aW5kb3c8LWZ1bmN0aW9uKGRmLGNocix5X2xpbSl7Z2dwbG90KGZpbHRlcihkZixjaHIxID09IGNociksIGFlcyhzdGFydDFfbWIpKSArCiAgZ2VvbV9saW5lKGFlcyh5PUtzX3dpbikpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHlsaW0oMCx5X2xpbSkgKwogIHhsYWIocGFzdGUoInBvc2l0aW9uIG9uIGNocm9tb3NvbWUiLCBjaHIsICIoTWIpIikpfSAKeV9saW08LTAuMDgKa3NfcGxvdF93aW5kb3coa3Nfd2luMTAwLCJYIix5X2xpbSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9dmxpbmVzLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArIAogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IC4zNSooNzEpLCB5ID0geV9saW0gLSAwLjAwNSwgbGFiZWwgPSAiUEFSMSIsc2l6ZT00KSArCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gLjUqKDcxKzI2MSksIHkgPSB5X2xpbSAtIDAuMDA1LCBsYWJlbCA9ICJPbGQgc2V4LWxpbmtlZFxuIHJlZ2lvbiIsc2l6ZSA9NCkgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IC41KigyNjErMzY3KSwgeSA9IHlfbGltIC0gMC4wMDUsIGxhYmVsID0gIk5ld1xuIHNleC1saW5rZWRcbiByZWdpb24iLHNpemU9NCkgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IC41KigzNjcrNTAwKSwgeSA9IHlfbGltIC0gMC4wMDUsIGxhYmVsID0gIlBBUjIiLHNpemU9NCkgCiNrc19wbG90X3dpbmRvdyhrc193aW41MCwiWCIsTkEpCiNnZ3NhdmUoImtzX2dlbmVzX3dpbmRvd19YX2p1bmUyMi5qcGciLGRwaT0zMDAsd2lkdGggPSA2LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIpCnlfbGltPC0wLjA1CiN5X2xpbTwtMC4yICMgbGltaXQgZG9lc250IHJlbW92ZSBkYXRhCmExd2luPC1rc19wbG90X3dpbmRvdyhrc193aW4xMDAsIkExIix5X2xpbSkKYTJ3aW48LWtzX3Bsb3Rfd2luZG93KGtzX3dpbjEwMCwiQTIiLHlfbGltKQphNHdpbjwta3NfcGxvdF93aW5kb3coa3Nfd2luMTAwLCJBNCIseV9saW0pCnh3aW48LSBrc19wbG90X3dpbmRvdyhrc193aW4xMDAsIlgiLHlfbGltKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD12bGluZXMsIGxpbmV0eXBlID0gImRhc2hlZCIpCmEyd2luCmNvd3Bsb3Q6OnBsb3RfZ3JpZChhMXdpbixhMndpbix4d2luLGE0d2luLG5yb3c9MSkKCiMjIHNhdmUgYXMgb25lIHBhbmVsCgojZ2dzYXZlKCJhbGxfY2hyX2tzXzEwMHdpbi5qcGciLGRwaT0zMDAsd2lkdGggPSAxMiwgaGVpZ2h0ID0gNCkKI2dnc2F2ZShwbG90ID0gYTF3aW4sICJhMV9rc18xMDB3aW4uanBnIixkcGk9MzAwLHdpZHRoID0gNiwgaGVpZ2h0ID0gNCkKI2dnc2F2ZShwbG90ID0gYTJ3aW4sICJhMl9rc18xMDB3aW4uanBnIixkcGk9MzAwLHdpZHRoID0gNiwgaGVpZ2h0ID0gNCkKI2dnc2F2ZShwbG90ID0gYTR3aW4sICJhNF9rc18xMDB3aW4uanBnIixkcGk9MzAwLHdpZHRoID0gNiwgaGVpZ2h0ID0gNCkKCmBgYAojIyMjIEludGVncmF0ZSBzYWxpY2lmb2xpdXMgaG9tb2xvZ3kgZGF0YQpgYGB7cn0Kc2FsX3JhdyA8LSBkYXRhLnRhYmxlOjpmcmVhZCgifi9Ecm9wYm94L3J1bWV4X3Bhbmdlbm9tZV9hbm5vdGF0aW9uL3BnX3NhbF93aWRlX3N5bm9ubHkudHh0IikKCnNhbGtleTwtcmVhZHI6OnJlYWRfZGVsaW0oImlucHV0X3RvX291dHB1dC50eHQiLGNvbF9uYW1lcyA9Yygib2xkIiwibmV3Iiksc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkKc2Fsa2V5PC1zYWxrZXkgJT4lIG11dGF0ZShmaXg9c3RyX3JlcGxhY2Uob2xkLCAiXFw9IiwgIlxcXyIpKSAlPiUKICBtdXRhdGUoLixmaXg9c3RyX3JlcGxhY2UoZml4LCAiXFw7IiwgIlxcXyIpKSAlPiUgc2VsZWN0KGZpeCxuZXcpCnNhbGtleTwtYXMuZGF0YS5mcmFtZShzYWxrZXkpCgpzYWxfZGYgPC0gc2FsX3JhdyAlPiUgZmlsdGVyKHNhbGljaWZvbGl1cyAhPSIiLGhhcDEhPSIiLGhhcDIhPSIiKSAlPiUgCiAgZHBseXI6OnNlbGVjdChpbnRlcnBDaHIsc2FsaWNpZm9saXVzLGhhcDEsaGFwMixzdGFydCkgJT4lIG11dGF0ZShzdGFydF9zYWxtYiA9IHN0YXJ0LzFlNikgJT4lIAogIGRwbHlyOjptdXRhdGUoc2FsY2hyID0gY2FzZV93aGVuKGludGVycENociA9PSBzYWxrZXlbMSwxXSB+IHNhbGtleVsxLDJdLCAKICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJwQ2hyID09IHNhbGtleVsyLDFdIH4gc2Fsa2V5WzIsMl0sIAogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnBDaHIgPT0gc2Fsa2V5WzMsMV0gfiBzYWxrZXlbMywyXSwKICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJwQ2hyID09IHNhbGtleVs0LDFdIH4gc2Fsa2V5WzQsMl0sCiAgICAgICAgICAgICAgICAgICAgICAgIGludGVycENociA9PSBzYWxrZXlbNSwxXSB+IHNhbGtleVs1LDJdLAogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnBDaHIgPT0gc2Fsa2V5WzYsMV0gfiBzYWxrZXlbNiwyXSwKICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJwQ2hyID09IHNhbGtleVs3LDFdIH4gc2Fsa2V5WzcsMl0sCiAgICAgICAgICAgICAgICAgICAgICAgIGludGVycENociA9PSBzYWxrZXlbOCwxXSB+IHNhbGtleVs4LDJdLAogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnBDaHIgPT0gc2Fsa2V5WzksMV0gfiBzYWxrZXlbOSwyXSwKICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJwQ2hyID09IHNhbGtleVsxMCwxXSB+IHNhbGtleVsxMCwyXSkpICMlPiUgCiAgI3VuaXRlKC4sIHNjYWZwb3MsYygic2FsY2hyIiwic3RhcnRfc2FsbWIiKSkKCgprc19kZl9zYWwgPC0gbGVmdF9qb2luKGtzX2RmX21kLCBzYWxfZGYsIGJ5ID0gYygibmFtZTEiPSJoYXAxIiwibmFtZTIiPSJoYXAyIikpCndpbmRvd21ha2VyX3NhbDwtIGZ1bmN0aW9uKGRmLHdpbixzdGFydCl7ZGYgJT4lCiAgZ3JvdXBfYnkoc2FsY2hyKSAlPiUKICBhcnJhbmdlKHNhbGljaWZvbGl1cyxzYWxjaHIsIHN0YXJ0KSAlPiUKICBtdXRhdGUoS3Nfd2luID0gc2xpZGVyOjpzbGlkZV9kYmwoS3MsIG1lZGlhbiwgLmJlZm9yZSA9IHdpbi8yLCAuYWZ0ZXIgPSB3aW4vMiwuc3RlcCA9IDEsLmNvbXBsZXRlID1UKSl9Cm9yZGVybGlzdDwtYygiU2NhZmZvbGRfNCIsIlNjYWZmb2xkXzgiLCJTY2FmZm9sZF83IiwKICAgICAgICAgICAgICJTY2FmZm9sZF81IiwiU2NhZmZvbGRfMyIsIlNjYWZmb2xkXzYiLCJTY2FmZm9sZF8xMCIsCiAgICAgICAgICAgICAiU2NhZmZvbGRfMSIsIlNjYWZmb2xkXzIiLCJTY2FmZm9sZF85IikKCmtzX2RmX3NhbCA8LSB0cmFuc2Zvcm0oa3NfZGZfc2FsLCBzYWxjaHIgPSBmYWN0b3Ioc2FsY2hyLCBsZXZlbHMgPSBvcmRlcmxpc3QpKQojbGV2ZWxzKGtzX2RmX3NhbCRzYWxjaHIpCmtzX3dpbjEwMF9zYWw8LXdpbmRvd21ha2VyX3NhbChrc19kZl9zYWwsd2luID0gMTAwLCBzdGFydF9zYWxtYikKa3Nfd2luMTBfc2FsPC13aW5kb3dtYWtlcl9zYWwoa3NfZGZfc2FsLCB3aW4gPSAxMCwgc3RhcnRfc2FsbWIpCiNrc19wbG90X3dpbmRvdyhrc19kZl9zYWwsIlgiLHlfbGltKSArIGdlb21fcmVjdChhZXMoY29sb3IgPSBpbnRlcnBDaHIpKQojZ2dwbG90KGZpbHRlcihrc19kZl9zYWwsY2hyMSA9PSJYIiksIGFlcyhzdGFydDFfbWIpKSArCiMgICBnZW9tX3BvaW50KGFlcyh5PUtzX3dpbiwgY29sb3VyID0gaW50ZXJwQ2hyKSkgKwojICAgdGhlbWVfY2xhc3NpYygpCiMgZ2dzYXZlKCJjb2xvcmRvdF9zYWxfa3MuanBnIixkcGk9MzAwLHdpZHRoPTYsIGhlaWdodD00KQojZ2dwbG90KGZpbHRlcihrc19kZl9zYWwsY2hyMSA9PSJYIiksIGFlcyhzdGFydDFfbWIpKSArCiMgIGdlb21fbGluZShhZXMoeT1Lc193aW4pKSArCiMgIHRoZW1lX2NsYXNzaWMoKQpgYGAKCiMjIyMgcmF3IEtzIGNvbG9yZWQgYnkgc2FsaWNpZm9saXVzIGNocm9tb3NvbWUgaG9tb2xvZ3kKYGBge3J9CmdncGxvdChmaWx0ZXIoa3NfZGZfc2FsLGNocjEgPT0iWCIpLCBhZXMoc3RhcnQxX21iLGdyb3VwID0gY2hyMSkpICsgIAogICBnZW9tX3BvaW50KGFlcyh5PUtzLCBjb2xvdXIgPSBzYWxjaHIpKSArCiAgIHRoZW1lX2NsYXNzaWMoKSArCiAgeWxpbSgwLDAuNSkgKwogIHRoZW1lKHBhbmVsLnNwYWNpbmcgPSB1bml0KDAsJ2xpbmVzJykpCgojIyBvcmRlcgojIHNjYWY0LHNjYWY4LHNjYWY3LHNjYWY1LHNjYWYzLHNjYWY2LHNjYWYxMApgYGAKIyMjIyByYXcgS3Mgb3JnYW5pemVkIGJ5IHNhbGljaWZvbGl1cyBnZW5lIG9yZGVyCmBgYHtyfQpnZ3Bsb3QoZmlsdGVyKGtzX2RmX3NhbCxjaHIxID09IlgiKSwgYWVzKHN0YXJ0X3NhbG1iLGdyb3VwID0gc2FsY2hyKSkgKyAgCiAgIGdlb21fcG9pbnQoYWVzKHk9S3MsIGNvbG91ciA9IHNhbGNocikpICsKICAgdGhlbWVfY2xhc3NpYygpICsKICAgZmFjZXRfZ3JpZCh+c2FsY2hyKSArCiAgeWxpbSgwLDAuNSkgKwogIHRoZW1lKHBhbmVsLnNwYWNpbmcgPSB1bml0KDAsJ2xpbmVzJykpIApgYGAKIyMjIyB3aW5kb3dlZCBLcyBmb3IgWCBnZW5lcyBpbiBzYWxpY2lmb2xpdXMgaG9tb2xvZ291cyBnZW5lIG9yZGVyCmBgYHtyfQpnZ3Bsb3QoZmlsdGVyKGtzX3dpbjEwMF9zYWwsY2hyMSA9PSJYIiksIGFlcyhzdGFydF9zYWxtYixncm91cCA9IHNhbGNocikpICsgIAogICBnZW9tX3BvaW50KGFlcyh5PUtzX3dpbiwgY29sb3VyID0gc2FsY2hyKSkgKwogICB0aGVtZV9jbGFzc2ljKCkgKwogICBmYWNldF9ncmlkKH5zYWxjaHIpICsKICAgeWxpbSgwLDAuMDUpICsKICAgdGhlbWUocGFuZWwuc3BhY2luZyA9IHVuaXQoMCwnbGluZXMnKSkKCmdncGxvdChmaWx0ZXIoa3Nfd2luMTBfc2FsLGNocjEgPT0iWCIsIHNhbGNociA9PSAiU2NhZmZvbGRfNyIpLCBhZXMoc3RhcnRfc2FsbWIsZ3JvdXAgPSBzYWxjaHIpKSArICAKICAgZ2VvbV9saW5lKGFlcyh5PUtzX3dpbiwgY29sb3VyID0gc2FsY2hyKSkgKwogICB0aGVtZV9jbGFzc2ljKCkgKwogICBmYWNldF9ncmlkKH5zYWxjaHIpICsKICAgeWxpbSgwLDAuMDUpICsKICAgdGhlbWUocGFuZWwuc3BhY2luZyA9IHVuaXQoMCwnbGluZXMnKSkKZ2dwbG90KGZpbHRlcihrc19kZl9zYWwsY2hyMSA9PSJYIixzYWxjaHIgPT0gIlNjYWZmb2xkXzciKSwgYWVzKHN0YXJ0MSxncm91cCA9IHNhbGNocikpICsgIAogICBnZW9tX3BvaW50KGFlcyh5PUtzLCBjb2xvdXIgPSBzYWxjaHIpKSArCiAgIHRoZW1lX2NsYXNzaWMoKSArCiAgIGZhY2V0X2dyaWQofnNhbGNocikgKwogICB5bGltKDAsMC4wNSkgKwogICB0aGVtZShwYW5lbC5zcGFjaW5nID0gdW5pdCgwLCdsaW5lcycpKQpgYGAKCiMjIyMgd2luZG93ZWQgS3MgZm9yIGFsbCBjaHIgaW4gc2FsIG9yZGVyCmBgYHtyfQpnZ3Bsb3QoZmlsdGVyKGtzX3dpbjEwMF9zYWwpLCBhZXMoc3RhcnRfc2FsbWIsZ3JvdXAgPSBzYWxjaHIpKSArICAKICAgZ2VvbV9wb2ludChhZXMoeT1Lc193aW4sIGNvbG91ciA9IHNhbGNocikpICsKICAgdGhlbWVfY2xhc3NpYygpICsKICAgZmFjZXRfZ3JpZCh+c2FsY2hyKSArCiAgeWxpbSgwLDAuMikgKwogIHRoZW1lKHBhbmVsLnNwYWNpbmcgPSB1bml0KDAsJ2xpbmVzJykpCmBgYAojIyMjIEtzIHdpbmRvd3MgWCwgbGluZSBhbmQgZG90cGxvdApgYGB7cn0KZ2dwbG90KGZpbHRlcihrc193aW4xMDBfc2FsLGNocjEgPT0iWCIpLCBhZXMoc3RhcnRfc2FsbWIsZ3JvdXAgPSBzYWxjaHIpKSArICAKICAgZ2VvbV9wb2ludChhZXMoeT1LcywgY29sb3VyID0gc2FsY2hyLGFscGhhPTAuNSkpICsKICBnZW9tX2xpbmUoYWVzKHk9S3Nfd2luKSkgKwogICB0aGVtZV9jbGFzc2ljKCkgKwogICBmYWNldF9ncmlkKH5zYWxjaHIpICsKICB5bGltKDAsMC4yKSAKI2dnc2F2ZSgiY29tYm9fS3Nfc2Fsb3JkLmpwZyIsZHBpPTMwMCx3aWR0aD0xMCxoZWlnaHQ9NCkKCmdncGxvdChmaWx0ZXIoa3Nfd2luMTAwX3NhbCxjaHIxID09IlgiKSwgYWVzKHN0YXJ0X3NhbG1iLGdyb3VwID0gc2FsY2hyKSkgKyAgCiAgIGdlb21fcG9pbnQoYWVzKHk9S3MsIGNvbG91ciA9IHNhbGNocixhbHBoYT0wLjUpKSArCiAgZ2VvbV9saW5lKGFlcyh5PUtzX3dpbikpICsKICAgdGhlbWVfY2xhc3NpYygpICsKICAgZmFjZXRfZ3JpZCh+c2FsY2hyKSArCiAgeWxpbSgwLDAuMikgCmBgYAojIyMgRmluYWwgcGxvdHMgZm9yIHB1YmxpY2F0aW9uCmBgYHtyfQpwdWJUaGVtZSA8LQogIHRoZW1lX2Nvd3Bsb3QoZm9udF9zaXplID0gMTIscmVsX3NtYWxsCT0wLjc1KSArCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiMjIyMgYmFzaWMgZm91ci1wYW5lbCB3aW5kb3dlZCBLcwpgYGB7cn0KI3B1YkNvbG91cnMgPC0gYygiIzJkOWRhNiIsIiM5OWI3MDAiLCIjOGE1M2I2IiwiI2JmNDgyNCIsIiMxNTI5NDQiKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKa3NwbG90MDM8LWdncGxvdChmaWx0ZXIoa3Nfd2luMTAwX2tzMywhZ3JlcGwoInNjYWZmb2xkIiwgY2hyMSkpLCBhZXMoc3RhcnQxX21iLGdyb3VwID0gY2hyMSkpICsgIAogICBnZW9tX2xpbmUoYWVzKHk9S3Nfd2luLCBjb2xvdXIgPSBjaHIxKSkgKwogICBmYWNldF9ncmlkKH5jaHIxLHNjYWxlcz0iZnJlZV94IikgKwogICB5bGltKDAsMC4wNSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogIHB1YlRoZW1lICsKICB4bGFiKCJNYXRlcm5hbCBIYXBsb3R5cGVcbnBvc2l0aW9uKE1iKSIpICsKICB5bGFiKCJNZWRpYW4gS3NcbigxMDAgZ2VuZSB3aW5kb3dzKSIpIAprc3Bsb3QKa3NwbG90MDMKCgoKYGBgCiMjIyMgcmVjcmVhdGUgZG90cGxvdCBmb3IgbXVsdGlwYW5lbCBwbG90CkludmVydCBzb21lIGNocnMgaW4gcGxvdApgYGB7cn0KIyMgcmVhZCBpbiBmaWxlIG9mIGNsZWFuZWQgQ09HRSBhbmNob3JzIGNyZWF0ZWQgZnJvbSBhbmNob3J3YXZlcGxvdHMuUm1kIAphbmNob3JzX21iPC1yZWFkX2RlbGltKCJkYXRhL2FuY2hvcnNfbWIudHh0IikKIyMKbWF4X3F1ZXJ5X21iIDwtIGZ1bmN0aW9uKGNocil7bWF4KGZpbHRlcihhbmNob3JzX21iLG5ld0NociA9PWNocikkcXVlcnlNYil9CiNtYXhfcXVlcnlfbWIoIlkiKSAgICAgICAgICAgICAgICAgICAgICAgICAgCgphbmNob3JzX2ludjwtYW5jaG9yc19tYiAlPiUgZ3JvdXBfYnkobmV3Q2hyKSAlPiUgCiAgbXV0YXRlKG5ld3N0YXJ0TWIgPSBjYXNlX3doZW4obmV3Q2hyID09ICJZIiB+IChtYXhfcXVlcnlfbWIoIlkiKSAtIHF1ZXJ5TWIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NociA9PSJBMSIgfiBxdWVyeU1iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NociA9PSJBMiIgfiAobWF4X3F1ZXJ5X21iKCJBMiIpIC0gcXVlcnlNYiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Q2hyID09IkE0IiB+IChtYXhfcXVlcnlfbWIoIkE0IikgLSBxdWVyeU1iKSkpCmBgYAoKCmBgYHtyfQphbmNob3JzX2ludiRuZXdDaHI8LWZhY3RvcihhbmNob3JzX2ludiRuZXdDaHIpCmR1bW15MiA8LSBkYXRhLmZyYW1lKG5ld0NociA9IGMoIkExIiwiQTIiLCJBNCIsIlkiKSkKZHVtbXkyJG5ld0NociA8LSBmYWN0b3IoZHVtbXkyJG5ld0NocikKZHVtbXkzIDwtIGRhdGEuZnJhbWUobmV3Q2hyID0gYygiWSIsIlkiLCJZIikpCmR1bW15MwpkdW1teTMkbmV3Q2hyIDwtIGZhY3RvcihkdW1teTMkbmV3Q2hyKQoKIyBOZXcgZmFjZXQgbGFiZWwgbmFtZXMgZm9yIGRvc2UgdmFyaWFibGUKY2hybGFicyA8LSBjKCJBMSIsICJBMiIsICJBNCIsICJYIC8gWTEgKyBZMiIpCm5hbWVzKGNocmxhYnMpIDwtIGMoIkExIiwgIkEyIiwgIkE0IiwgIlkiKQoKCgpkYXRfdGV4dCA8LSBkYXRhLmZyYW1lKAogIGxhYmVsID0gYygiUEFSMSIsIk9sZFxuU0xSIiwiTmV3XG5TTFIiLCJQQVIyIiksCiAgbmV3Q2hyICAgPSBjKCJZIiwiWSIsIlkiLCJZIiksCiAgeCA9IGMoMC4zKjcxLCAuNSooNzErMjYxKSwgLjUqKDI2MSszNjcpLC41KigzNjcrNTAwKSksCiAgeSA9IGMoNDAwLDQwMCw0MDAsNDAwKSkKCmRvdHBsb3Q8LWdncGxvdChhbmNob3JzX2ludixhZXMocmVmZXJlbmNlTWIsbmV3c3RhcnRNYikpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhZXMoY29sb3I9cXVlcnlDaHIpKSArCiAgcHViVGhlbWUgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogIGZhY2V0X2dyaWQofm5ld0NocixzY2FsZXM9ImZyZWVfeCIsbGFiZWxsZXIgPSBsYWJlbGxlcihuZXdDaHIgPSBjaHJsYWJzKSkgKwogIGdlb21fdmxpbmUoZGF0YSA9IGR1bW15MywgYWVzKHhpbnRlcmNlcHQgPSA3MSksbGluZXR5cGUgPSAnZGFzaGVkJykgKwogIGdlb21fdmxpbmUoZGF0YSA9IGR1bW15MywgYWVzKHhpbnRlcmNlcHQgPSAyNjEpLGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsKICBnZW9tX3ZsaW5lKGRhdGEgPSBkdW1teTMsIGFlcyh4aW50ZXJjZXB0ID0gMzY3KSxsaW5ldHlwZSA9ICdkYXNoZWQnKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBkYXRfdGV4dCxzaXplID0gNCxtYXBwaW5nID0gYWVzKHggPSB4LCB5ID0geSwgbGFiZWwgPSBsYWJlbCkpICsKICB5bGltKDAsNDMwKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSkrCiAgICB5bGFiKCJQYXRlcm5hbCBIYXBsb3R5cGVcbnBvc2l0aW9uKE1iKSIpIAoKZG90cGxvdCAgCmBgYAoKIyMjIyBtYWtpbmcgaXQgbXVsdGktcGFuZWwKYGBge3J9CmNvbWJvcGxvdDwtY293cGxvdDo6cGxvdF9ncmlkKGRvdHBsb3Qsa3NwbG90LG5yb3c9MixhbGlnbj0idiIsYXhpcz0ibHIiKQpjb21ib3Bsb3QgCiNhbGlnbmVkcGxvdDwtYWxpZ25fcGxvdHMoZG90cGxvdCxrc3Bsb3QsYWxpZ249Imh2IixheGlzPSJ0YmxyIikKI2dnZHJhdyhhbGlnbmVkcGxvdCkKI2dnc2F2ZSgiS3NfZG90cGxvdF9jb21iby5qcGciLGRwaT0zMDAsd2lkdGggPSA4LGhlaWdodCA9NCkKYGBgCk5lZWQgdG8gc2VwYXJhdGUgb3V0IFkxIGFuZCBZMj8KIyMjIyBjb2xvciBieSBoYXAyIGNocm9tb3NvbWUKYGBge3J9CgpkdW1teTQ8LWRhdGEuZnJhbWUoY2hyMSA9IGMoIlgiLCJYIiwiWCIpKQpkdW1teTQkY2hyMSA8LSBmYWN0b3IoZHVtbXk0JGNocjEpCgprc3Bsb3QyPC1nZ3Bsb3QoZmlsdGVyKGtzX3dpbjEwMCwhZ3JlcGwoInNjYWZmb2xkIiwgY2hyMSkpLCBhZXMoc3RhcnQxX21iLGdyb3VwID0gY2hyMSkpICsgIAogICBnZW9tX2xpbmUoYWVzKHk9S3Nfd2luLCBjb2xvdXIgPSBjaHIyKSkgKwogICBmYWNldF9ncmlkKH5jaHIxLHNjYWxlcz0iZnJlZV94IikgKwogICB5bGltKDAsMC4wNSkgKwogICBwdWJUaGVtZSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArCiAgZ2VvbV92bGluZShkYXRhID0gZHVtbXk0LCBhZXMoeGludGVyY2VwdCA9IDcxKSxsaW5ldHlwZSA9ICdkYXNoZWQnKSArCiAgZ2VvbV92bGluZShkYXRhID0gZHVtbXk0LCBhZXMoeGludGVyY2VwdCA9IDI2MSksbGluZXR5cGUgPSAnZGFzaGVkJykgKwogIGdlb21fdmxpbmUoZGF0YSA9IGR1bW15NCwgYWVzKHhpbnRlcmNlcHQgPSAzNjcpLGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsKICB4bGFiKCJNYXRlcm5hbCBIYXBsb3R5cGVcbnBvc2l0aW9uKE1iKSIpICsKICB5bGFiKCJNZWRpYW4gS3NcbigxMDAgZ2VuZSB3aW5kb3dzKSIpICsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpCmtzcGxvdDIKCmNvbWJvcGxvdDI8LWNvd3Bsb3Q6OnBsb3RfZ3JpZChkb3RwbG90LGtzcGxvdDIsbnJvdz0yLGFsaWduPSJ2IixheGlzPSJsciIpCmNvbWJvcGxvdDIKI2dnc2F2ZSgia3NwbG90X2RvdHBsb3Rfc2FsY29sb3JzLmpwZyIsZHBpPTMwMCx3aWR0aCA9MTAsaGVpZ2h0PTcpCiNnZ3NhdmUoImtzcGxvdF9kb3RwbG90X3NhbGNvbG9ycy5wbmciLGRwaT0zMDAsd2lkdGggPTEwLGhlaWdodD03LGJnID0gIndoaXRlIikKZ2dzYXZlKCJrc3Bsb3RfZG90cGxvdF9zYWxjb2xvcnNfcmV6aXplLnBkZiIsZHBpPTMwMCx3aWR0aCA9MTAsaGVpZ2h0PTcpCgpgYGAKVG8gZG86CiogbmV4dDpnZW5lIGxvc3MgcGxvdHMsIEFTRQoqIHNhdmUgYXMganBnIGFuZCBQTkcgZm9yIHB1YgoqIGZpZ3VyZSBsZWdlbmRzIGluIHRleHQgYmVsb3cgKGdvb2cgZG9jKQoqIGxpc3Qgb2Ygc2lsZW5jZWQgZ2VuZXMgZnJvbSBBU0UgYW5hbHlzaXMKICAgLSBjb21iaW5lIHcgVEUKCiMjIGNoaSBzcXVhcmUKYGBge3J9CiMjIyBLUyAgc2FsCmZpc2h0YWI8LWtzX2RmX3NhbCAlPiUgZmlsdGVyKCFpcy5uYShzYWxpY2lmb2xpdXMpKSAlPiVncm91cF9ieShzYWxjaHIsS3M+MC4wMykgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lIGZpbHRlcihzYWxjaHIgPT0gIlNjYWZmb2xkXzcifHNhbGNociA9PSAiU2NhZmZvbGRfOCIpICU+JSAKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc2FsY2hyLHZhbHVlc19mcm9tID0gbikKZmlzaG1hdDwtZmlzaHRhYiAlPiUgc2VsZWN0KDIsMykgJT4lIGFzLm1hdHJpeCgpCmZ0PC1maXNoZXIudGVzdChmaXNobWF0KQpmaXNodGFiCmZ0JGVzdGltYXRlCmN0PC1jaGlzcS50ZXN0KGZpc2htYXQsY29ycmVjdCA9IEYpCmN0CmBgYApgYGB7cn0KCmBgYAoKCgoKCg==